/*
 * 球泡灯代码。2024.3.1-4.16
 
 远程服务端ip 
 */



#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_mac.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_bt.h"
#include "esp_task_wdt.h" //

#include "esp_blufi_api.h"
#include "blufi_example.h"
#include "esp_timer.h"
#include "esp_blufi.h"
#include <time.h>
#include <sys/time.h>
#include "esp_attr.h"
#include "esp_sleep.h"
#include "esp_netif_sntp.h"
#include "lwip/ip_addr.h"
#include "esp_sntp.h"
#include "sdkconfig.h"
#include <unistd.h>
#include <sys/socket.h>
#include <errno.h>
#include <netdb.h>            
#include <arpa/inet.h>
#include "esp_netif.h"
#include <time.h> 
 
#include "esp_ota_ops.h"
#include "esp_http_client.h"
#include "esp_https_ota.h"
 
#ifdef CONFIG_EXAMPLE_USE_CERT_BUNDLE
#include "esp_crt_bundle.h"
#endif

#include "nvs.h"
 //http获取地名对应的utc偏移
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"
#include "sdkconfig.h"
#include "cJSON.h"

#define OTA_URL_SIZE 256
 


#if defined(CONFIG_EXAMPLE_IPV4)
#define HOST_IP_ADDR CONFIG_EXAMPLE_IPV4_ADDR
#elif defined(CONFIG_EXAMPLE_SOCKET_IP_INPUT_STDIN)
#define HOST_IP_ADDR ""
#endif

#define PORT CONFIG_EXAMPLE_PORT

#include "driver/ledc.h"
#include "esp_err.h"

#define LEDC_TIMER              LEDC_TIMER_0
#define LEDC_MODE               LEDC_LOW_SPEED_MODE
#define LEDC_OUTPUT_IO_C          (32) // Define the output GPIO
#define LEDC_OUTPUT_IO_M          (33)
#define LEDC_CHANNEL_0            LEDC_CHANNEL_0
#define LEDC_CHANNEL_1            LEDC_CHANNEL_1
#define LEDC_DUTY_RES           LEDC_TIMER_13_BIT // Set duty resolution to 13 bits

#define LEDC_DUTY               (8192)
#define LEDC_FREQUENCY          (4000) // Frequency in Hertz. Set frequency at 4 kHz
 
#define EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY CONFIG_EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY
#define EXAMPLE_INVALID_REASON                255
#define EXAMPLE_INVALID_RSSI                  -128
#define WIFI_LIST_NUM   10
 
#define WEB_SERVER "www.worldtimeapi.org"  //世界时间APl服务器
#define WEB_PORT "80"
#define WEB_PATH "/"
#define WEB_URL  "http://worldtimeapi.org/api/timezone/"       
 
#define fan 20   //指的是指令长度
 
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 48
#endif
#if CONFIG_EXAMPLE_CONNECT_WIFI
#include "esp_wifi.h"
#endif

#define HASH_LEN 32

#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
/* The interface name value can refer to if_desc in esp_netif_defaults.h */
#if CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF_ETH
static const char *bind_interface_name = EXAMPLE_NETIF_DESC_ETH;
#elif CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF_STA
static const char *bind_interface_name = EXAMPLE_NETIF_DESC_STA;
#endif
#endif


static void http_get_task(void);

static const char *TAG1 = "simple_ota_example";
static void example_ledc_init(void);
void led_test_c(uint32_t c);
void led_test_m(uint32_t m);
void led_test_fade_c(uint32_t c);
void led_test_fade_m(uint32_t m);
void led_test_sewen(uint32_t m);

void sntp_set_time(char *t);

static const char *TAG = "example";
uint8_t rx_buffer[100];
char zbuffer[100];

uint8_t sendbuf[fan];
int change ;
int morning1,morning2;//节律开始时间
int night1,night2;//节律结束时间
char time1[6];//存储UTc及偏移
//char numStr[40];//存储地名  xxx/xxx
char url[200];//存放http请求
uint32_t nowlight = 2700;
uint16_t crc;
uint16_t crc1;
uint16_t verify_crc16(uint8_t *buffer, uint32_t len);
static void example_event_callback(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param);
void tcp_client(void *arg);
void blufi(void *arg);
void once_timer(int x);
void end_timer(int x);
static void oneshot_timer_callback(void* arg);
static void endshot_timer_callback(void* arg);
static const char *REQUEST ;


static wifi_config_t sta_config;
static wifi_config_t ap_config;


static EventGroupHandle_t wifi_event_group;


const int CONNECTED_BIT = BIT0;

static uint8_t example_wifi_retry = 0;


static bool gl_sta_connected = false;
static bool gl_sta_got_ip = false;
static bool ble_is_connected = false;
static uint8_t gl_sta_bssid[6];
static uint8_t gl_sta_ssid[32];
static int gl_sta_ssid_len;
static wifi_sta_list_t gl_sta_list;
static bool gl_sta_is_connecting = false;
static esp_blufi_extra_info_t gl_sta_conn_info;


RTC_DATA_ATTR static int boot_count = 0;

static void obtain_time(void);
void sntp(void);
void sntp_time(void *arg );
void re_wifi(void *arg);
void become(void);
static void get_sha256_of_partitions(void);
static void print_sha256(const uint8_t *image_hash, const char *label);
void simple_ota_example_task(void *pvParameter);
	
static void example_record_wifi_conn_info(int rssi, uint8_t reason)
{
    memset(&gl_sta_conn_info, 0, sizeof(esp_blufi_extra_info_t));
    if (gl_sta_is_connecting) {
        gl_sta_conn_info.sta_max_conn_retry_set = true;
        gl_sta_conn_info.sta_max_conn_retry = EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY;
    } else {
        gl_sta_conn_info.sta_conn_rssi_set = true;
        gl_sta_conn_info.sta_conn_rssi = rssi;
        gl_sta_conn_info.sta_conn_end_reason_set = true;
        gl_sta_conn_info.sta_conn_end_reason = reason;
    }
}

static void example_wifi_connect(void)
{
    example_wifi_retry = 0;
    gl_sta_is_connecting = (esp_wifi_connect() == ESP_OK);
    example_record_wifi_conn_info(EXAMPLE_INVALID_RSSI, EXAMPLE_INVALID_REASON);
}

static bool example_wifi_reconnect(void)
{
    bool ret;
    if (gl_sta_is_connecting && example_wifi_retry++ < EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY) {
        BLUFI_INFO("BLUFI WiFi starts reconnection\n");
        gl_sta_is_connecting = (esp_wifi_connect() == ESP_OK);
        example_record_wifi_conn_info(EXAMPLE_INVALID_RSSI, EXAMPLE_INVALID_REASON);
        ret = true;
    } else {
        ret = false;
    }
    return ret;
}

static int softap_get_current_connection_number(void)
{
    esp_err_t ret;
    ret = esp_wifi_ap_get_sta_list(&gl_sta_list);
    if (ret == ESP_OK)
    {
        return gl_sta_list.num;
    }

    return 0;
}

static void ip_event_handler(void* arg, esp_event_base_t event_base,
                                int32_t event_id, void* event_data)
{
    wifi_mode_t mode;

    switch (event_id) {
    case IP_EVENT_STA_GOT_IP: {
        esp_blufi_extra_info_t info;

        xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
        esp_wifi_get_mode(&mode);

        memset(&info, 0, sizeof(esp_blufi_extra_info_t));
        memcpy(info.sta_bssid, gl_sta_bssid, 6);
        info.sta_bssid_set = true;
        info.sta_ssid = gl_sta_ssid;
        info.sta_ssid_len = gl_sta_ssid_len;
        gl_sta_got_ip = true;

        xTaskCreate(tcp_client,"task1",4096,NULL,1,NULL);
        if (ble_is_connected == true) {
            esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_SUCCESS, softap_get_current_connection_number(), &info);



        } else {
            BLUFI_INFO("BLUFI BLE is not connected yet\n");
        }
        break;
    }
    default:
        break;
    }
    return;
}

static void wifi_event_handler(void* arg, esp_event_base_t event_base,
                                int32_t event_id, void* event_data)
{
    wifi_event_sta_connected_t *event;
    wifi_event_sta_disconnected_t *disconnected_event;
    wifi_mode_t mode;

    switch (event_id) {
		
    case WIFI_EVENT_STA_START:
		
        example_wifi_connect();

        break;
    case WIFI_EVENT_STA_CONNECTED:
        gl_sta_connected = true;
        gl_sta_is_connecting = false;
        event = (wifi_event_sta_connected_t*) event_data;
        memcpy(gl_sta_bssid, event->bssid, 6);
        memcpy(gl_sta_ssid, event->ssid, event->ssid_len);
        gl_sta_ssid_len = event->ssid_len;


        sntp();
        //sntp_set_time();
        break;
    case WIFI_EVENT_STA_DISCONNECTED:
         //example_wifi_reconnect();

         xTaskCreate(re_wifi,"task9",4096,NULL,1,NULL);
        


        gl_sta_connected = false;
        gl_sta_got_ip = false;
        memset(gl_sta_ssid, 0, 32);
        memset(gl_sta_bssid, 0, 6);
        gl_sta_ssid_len = 0;
        xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
        break;
    
    case WIFI_EVENT_SCAN_DONE: {
        uint16_t apCount = 0;
        esp_wifi_scan_get_ap_num(&apCount);
        if (apCount == 0) {
            BLUFI_INFO("Nothing AP found");
            break;
        }
        wifi_ap_record_t *ap_list = (wifi_ap_record_t *)malloc(sizeof(wifi_ap_record_t) * apCount);
        if (!ap_list) {
            BLUFI_ERROR("malloc error, ap_list is NULL");
            break;
        }
        ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&apCount, ap_list));
        esp_blufi_ap_record_t * blufi_ap_list = (esp_blufi_ap_record_t *)malloc(apCount *
         sizeof(esp_blufi_ap_record_t));
        if (!blufi_ap_list) {
            if (ap_list) {
                free(ap_list);
            }
            BLUFI_ERROR("malloc error, blufi_ap_list is NULL");
            break;
        }
        for (int i = 0; i < apCount; ++i)
        {
            blufi_ap_list[i].rssi = ap_list[i].rssi;
            memcpy(blufi_ap_list[i].ssid, ap_list[i].ssid, sizeof(ap_list[i].ssid));
        }

        if (ble_is_connected == true) {
            esp_blufi_send_wifi_list(apCount, blufi_ap_list);
        } else {
            BLUFI_INFO("BLUFI BLE is not connected yet\n");
        }

        esp_wifi_scan_stop();
        free(ap_list);
        free(blufi_ap_list);
        break;
    }
   
    default:
        break;
    }
    return;
}

static void initialise_wifi(void)
{
    ESP_ERROR_CHECK(esp_netif_init());
    wifi_event_group = xEventGroupCreate();
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
    assert(sta_netif);
    esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
    assert(ap_netif);
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL));

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
    example_record_wifi_conn_info(EXAMPLE_INVALID_RSSI, EXAMPLE_INVALID_REASON);
    ESP_ERROR_CHECK( esp_wifi_start() );
}

static esp_blufi_callbacks_t example_callbacks = {
    .event_cb = example_event_callback,
    .negotiate_data_handler = blufi_dh_negotiate_data_handler,
    .encrypt_func = blufi_aes_encrypt,
    .decrypt_func = blufi_aes_decrypt,
    .checksum_func = blufi_crc_checksum,
};

static void example_event_callback(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param)
{
   
    switch (event) {
    case ESP_BLUFI_EVENT_INIT_FINISH:
        BLUFI_INFO("BLUFI init finish\n");

        esp_blufi_adv_start();
        break;
    case ESP_BLUFI_EVENT_DEINIT_FINISH:
        BLUFI_INFO("BLUFI deinit finish\n");
        break;
    case ESP_BLUFI_EVENT_BLE_CONNECT:
        BLUFI_INFO("BLUFI ble connect\n");
        ble_is_connected = true;
        esp_blufi_adv_stop();
        blufi_security_init();
        break;
    case ESP_BLUFI_EVENT_BLE_DISCONNECT:
        BLUFI_INFO("BLUFI ble disconnect\n");
        ble_is_connected = false;
        blufi_security_deinit();
        esp_blufi_adv_start();
        break;
    case ESP_BLUFI_EVENT_SET_WIFI_OPMODE:
        BLUFI_INFO("BLUFI Set WIFI opmode %d\n", param->wifi_mode.op_mode);
        ESP_ERROR_CHECK( esp_wifi_set_mode(param->wifi_mode.op_mode) );
        break;
    case ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP:
        BLUFI_INFO("BLUFI requset wifi connect to AP\n");
        
        esp_wifi_disconnect();
        example_wifi_connect();
        break;
    case ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP:
        BLUFI_INFO("BLUFI requset wifi disconnect from AP\n");
        esp_wifi_disconnect();
        break;
    case ESP_BLUFI_EVENT_REPORT_ERROR:
        BLUFI_ERROR("BLUFI report error, error code %d\n", param->report_error.state);
        esp_blufi_send_error_info(param->report_error.state);
        break;
    case ESP_BLUFI_EVENT_GET_WIFI_STATUS: {
        wifi_mode_t mode;
        esp_blufi_extra_info_t info;

        esp_wifi_get_mode(&mode);

        if (gl_sta_connected) {
            memset(&info, 0, sizeof(esp_blufi_extra_info_t));
            memcpy(info.sta_bssid, gl_sta_bssid, 6);
            info.sta_bssid_set = true;
            info.sta_ssid = gl_sta_ssid;
            info.sta_ssid_len = gl_sta_ssid_len;
            esp_blufi_send_wifi_conn_report(mode, gl_sta_got_ip ? ESP_BLUFI_STA_CONN_SUCCESS :
             ESP_BLUFI_STA_NO_IP, softap_get_current_connection_number(), &info);
        } else if (gl_sta_is_connecting) {
            esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONNECTING,
             softap_get_current_connection_number(), &gl_sta_conn_info);
        } else {
            esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_FAIL,
            softap_get_current_connection_number(), &gl_sta_conn_info);
        }
        BLUFI_INFO("BLUFI get wifi status from AP\n");

        break;
    }
    case ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE:
        BLUFI_INFO("blufi close a gatt connection");
        esp_blufi_disconnect();
        break;
    case ESP_BLUFI_EVENT_DEAUTHENTICATE_STA:
        /* TODO */
        break;
	case ESP_BLUFI_EVENT_RECV_STA_BSSID:
        memcpy(sta_config.sta.bssid, param->sta_bssid.bssid, 6);
        sta_config.sta.bssid_set = 1;
        esp_wifi_set_config(WIFI_IF_STA, &sta_config);
        BLUFI_INFO("Recv STA BSSID %s\n", sta_config.sta.ssid);
        break;
	case ESP_BLUFI_EVENT_RECV_STA_SSID:
        strncpy((char *)sta_config.sta.ssid, (char *)param->sta_ssid.ssid, param->sta_ssid.ssid_len);
        sta_config.sta.ssid[param->sta_ssid.ssid_len] = '\0';
        esp_wifi_set_config(WIFI_IF_STA, &sta_config);
        BLUFI_INFO("Recv STA SSID %s\n", sta_config.sta.ssid);
        break;
	case ESP_BLUFI_EVENT_RECV_STA_PASSWD:
        strncpy((char *)sta_config.sta.password, (char *)param->sta_passwd.passwd, param->sta_passwd.passwd_len);
        sta_config.sta.password[param->sta_passwd.passwd_len] = '\0';
        esp_wifi_set_config(WIFI_IF_STA, &sta_config);
        BLUFI_INFO("Recv STA PASSWORD %s\n", sta_config.sta.password);
        break;
	case ESP_BLUFI_EVENT_RECV_SOFTAP_SSID:
        strncpy((char *)ap_config.ap.ssid, (char *)param->softap_ssid.ssid, param->softap_ssid.ssid_len);
        ap_config.ap.ssid[param->softap_ssid.ssid_len] = '\0';
        ap_config.ap.ssid_len = param->softap_ssid.ssid_len;
        esp_wifi_set_config(WIFI_IF_AP, &ap_config);
        BLUFI_INFO("Recv SOFTAP SSID %s, ssid len %d\n", ap_config.ap.ssid, ap_config.ap.ssid_len);
        break;
	case ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD:
        strncpy((char *)ap_config.ap.password, (char *)param->softap_passwd.passwd,
         param->softap_passwd.passwd_len);
        ap_config.ap.password[param->softap_passwd.passwd_len] = '\0';
        esp_wifi_set_config(WIFI_IF_AP, &ap_config);
        BLUFI_INFO("Recv SOFTAP PASSWORD %s len = %d\n", ap_config.ap.password, param->softap_passwd.passwd_len);
        break;
	case ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM:
        if (param->softap_max_conn_num.max_conn_num > 4) {
            return;
        }
        ap_config.ap.max_connection = param->softap_max_conn_num.max_conn_num;
        esp_wifi_set_config(WIFI_IF_AP, &ap_config);
        BLUFI_INFO("Recv SOFTAP MAX CONN NUM %d\n", ap_config.ap.max_connection);
        break;
	case ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE:
        if (param->softap_auth_mode.auth_mode >= WIFI_AUTH_MAX) {
            return;
        }
        ap_config.ap.authmode = param->softap_auth_mode.auth_mode;
        esp_wifi_set_config(WIFI_IF_AP, &ap_config);
        BLUFI_INFO("Recv SOFTAP AUTH MODE %d\n", ap_config.ap.authmode);
        break;
	case ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL:
        if (param->softap_channel.channel > 13) {
            return;
        }
        ap_config.ap.channel = param->softap_channel.channel;
        esp_wifi_set_config(WIFI_IF_AP, &ap_config);
        BLUFI_INFO("Recv SOFTAP CHANNEL %d\n", ap_config.ap.channel);
        break;
    case ESP_BLUFI_EVENT_GET_WIFI_LIST:{
        wifi_scan_config_t scanConf = {
            .ssid = NULL,
            .bssid = NULL,
            .channel = 0,
            .show_hidden = false
        };
        esp_err_t ret = esp_wifi_scan_start(&scanConf, true);
        if (ret != ESP_OK) {
            esp_blufi_send_error_info(ESP_BLUFI_WIFI_SCAN_FAIL);
        }
        break;
    }
    case ESP_BLUFI_EVENT_RECV_CUSTOM_DATA:
        BLUFI_INFO("Recv Custom Data %" PRIu32 "\n", param->custom_data.data_len);
        esp_log_buffer_hex("Custom Data", param->custom_data.data, param->custom_data.data_len);
        break;
	
    default:
        break;
    }
}
void tcp_client(void *arg)
{

    //char rx_buffer[128];
	char host_ip[] = HOST_IP_ADDR;
	int addr_family = 0;
	int ip_protocol = 0;
    
	while(1){
		
		

#if defined(CONFIG_EXAMPLE_IPV4)
		struct sockaddr_in dest_addr;
		inet_pton(AF_INET, host_ip, &dest_addr.sin_addr);
		dest_addr.sin_family = AF_INET;
		dest_addr.sin_port = htons(PORT);
		addr_family = AF_INET;
		ip_protocol = IPPROTO_IP;

#endif

		int sock =  socket(addr_family, SOCK_STREAM, ip_protocol);
		if (sock < 0) {
			
			ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);

		}
			ESP_LOGI(TAG, "Socket created, connecting to %s:%d", host_ip, PORT);


		int err = connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
		if (err != 0) {
			ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);

		}
				

		while(1){
			
			
			int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
			//int l =recv(sock, zbuffer, sizeof(zbuffer) - 1, 0);
			for (int i = 0; i < len ; i++) {
				zbuffer[i] = (char)rx_buffer[i];
			}
			if (len < 0) {
                ESP_LOGE(TAG, "recv failed: errno %d", errno);
                break;
            } else {
				
				
				crc = verify_crc16(rx_buffer,len-2);
				crc1 = rx_buffer[len-2]+256*rx_buffer[len-1];
				  
				sendbuf[0]=153;
				sendbuf[1]=2;
				
				
				if ((rx_buffer[0] == 153) && (rx_buffer[1] == 1) && (rx_buffer[2] == 1) && (rx_buffer[4] == 1) && (crc == crc1)){
					

					led_test_c(50); //开
					led_test_m(50);
					sendbuf[2] = 0;
					sendbuf[3] =50;
				  
					crc = verify_crc16(sendbuf,fan-2);
					sendbuf[fan-2] = (crc & 0xFF);
					sendbuf[fan-1]=(crc >> 8);
					send(sock,sendbuf,fan,0);
				   
				}
			   if ((rx_buffer[0] == 153) && (rx_buffer[1] == 1) && (rx_buffer[2] == 1) && (rx_buffer[4] == 0)&&(crc == crc1) ){
				   led_test_c(0); //灭
				   led_test_m(0);
				  
				   sendbuf[2] = 0;
				   sendbuf[3] = 0;
				   
				   crc = verify_crc16(sendbuf,fan-2);
				   sendbuf[fan-2] = (crc & 0xFF);
				   sendbuf[fan-1]=(crc >> 8);
				   send(sock,sendbuf,fan,0);
				}
				if ((rx_buffer[0] == 153) && (rx_buffer[1] == 1) && (rx_buffer[2] == 2) && (crc == crc1)) {
					
					if (change <= 6500 && change > 4600) {    //亮度
						
						if (rx_buffer[4] == 100) {
							
							led_test_c(100); 
						} else {
							led_test_fade_c(rx_buffer[3]);
						}
					}
					
					if (change >= 2700 && change < 4600) {
					
						if(rx_buffer[4] == 100) {
							led_test_m(100); 
						} else {
					
							led_test_fade_m(rx_buffer[3]);
						}
					}
				   
				  
					sendbuf[2] = 0;
					sendbuf[3] = rx_buffer[3];
					
					crc = verify_crc16(sendbuf,fan-2);
					sendbuf[fan-2] = (crc & 0xFF);
					sendbuf[fan-1]=(crc >> 8);
					send(sock,sendbuf,fan,0);
					 
				}
				if ((rx_buffer[0] == 153)&&(rx_buffer[1] == 1) && (rx_buffer[2] == 3)&&(crc == crc1)) {
					uint32_t rx=rx_buffer[3]*256+rx_buffer[4];
					
				   
					led_test_sewen(rx);//色温
					change= rx;
					
					sendbuf[2] = 0;
					sendbuf[4] = rx_buffer[3];
					sendbuf[5] = rx_buffer[4];
					
					crc = verify_crc16(sendbuf,fan-2);
					sendbuf[fan-2] = (crc & 0xFF);
					sendbuf[fan-1]=(crc >> 8);
					send(sock,sendbuf,fan,0);
					
				}
	  
				if ((rx_buffer[0] == 153) && (rx_buffer[1] == 1) && (rx_buffer[2] == 4)){  //模式
					
					if ((rx_buffer[3] == 1) && (crc == crc1)) { //朦胧
						BLUFI_INFO("1");
						sendbuf[2] = 1;
						led_test_fade_c(49);
						led_test_fade_m(1);
					}
					if ((rx_buffer[3] == 2) && (crc == crc1)) {//温馨
						BLUFI_INFO("2");
						sendbuf[2] = 2;
						led_test_fade_c(20);
						led_test_fade_m(60);
					}
					if ((rx_buffer[3] == 3) && (crc == crc1)) {//观影
						BLUFI_INFO("3");
						led_test_fade_c(1);
						led_test_fade_m(30);
						sendbuf[2] = 3;
					}
					if ((rx_buffer[3] == 4) && (crc == crc1)) { //明亮
						
						BLUFI_INFO("4");
						led_test_c(100);
						led_test_fade_m(50);
						sendbuf[2] = 4;
					}
					if ((rx_buffer[3] == 5) && (crc == crc1)) { //节律
						
						morning1 = rx_buffer[4];
						morning2 = rx_buffer[5];
						night1   = rx_buffer[6];
						night2   = rx_buffer[7];
						sendbuf[2] = 5;
						xTaskCreate(sntp_time, "jielv_task",4096 , NULL, 1, NULL);
						// sntp_time();
					}
					
					crc = verify_crc16(sendbuf,fan-2);
					sendbuf[fan-2] = (crc & 0xFF);
					sendbuf[fan-1]=(crc >> 8);
					send(sock,sendbuf,fan,0);
				}
				
				
				if ((rx_buffer[0] == 153) && (rx_buffer[1] == 1) && (rx_buffer[2] == 6) && (crc == crc1)) {
					//ota
					
					
					 xTaskCreate(&simple_ota_example_task, "ota_example_task",8192 , NULL, 5, NULL);
					 
					crc = verify_crc16(sendbuf,fan-2);
					
					sendbuf[fan-2] = (crc & 0xFF);
					sendbuf[fan-1]=(crc >> 8);
					send(sock,sendbuf,fan,0);
				}
				
				if ((zbuffer[0] == '9' ) && (zbuffer[1] == '9' ) && (zbuffer[7] == '5')) { //设置时区
				    BLUFI_INFO("ffffff");
					char numStr[20];
					memset(numStr, 0, sizeof(numStr));

					memcpy(numStr, zbuffer + 9, strlen(zbuffer)-9);
					numStr[strlen(zbuffer)-9] = '\0'; 
					printf("%s\n",numStr);
					sprintf(url, "GET http://worldtimeapi.org/api/timezone/%s HTTP/1.0\r\n""Host: %s\r\n""\r\n", numStr, WEB_SERVER);
					REQUEST = url; 
					http_get_task();
					become();
					sntp_set_time(time1);//  
					send(sock,sendbuf,fan,0);
						
					memset(zbuffer, 0, sizeof(zbuffer));
				}
			} 
				 
			/* 	 
			if (l > 0){
				if ((zbuffer[0] == '9' ) && (zbuffer[1] == '9' ) && (zbuffer[7] == '5')) { //设置时区
					char numStr[20];
					memset(numStr, 0, sizeof(numStr));

					memcpy(numStr, zbuffer + 9, strlen(zbuffer)-9);
					numStr[strlen(zbuffer)-9] = '\0'; 
					printf("%s\n",numStr);
					sprintf(url, "GET http://worldtimeapi.org/api/timezone/%s HTTP/1.0\r\n""Host: %s\r\n""\r\n", numStr, WEB_SERVER);
					REQUEST = url; 
					http_get_task();
					become();
					sntp_set_time(time1);//  
					send(sock,sendbuf,fan,0);
						
					memset(zbuffer, 0, sizeof(zbuffer));
						
				} 
			}	
			    */
			
		}
			
		if (sock != -1) {
			
			ESP_LOGE(TAG, "Shutting down socket and restarting...");
			shutdown(sock, 0);
			close(sock);
		}
	}
}

void re_wifi(void *arg){
	
    wifi_ap_record_t ap_info;
	
    while(1){
        if (esp_wifi_sta_get_ap_info(&ap_info) != ESP_OK) {
			
		    esp_wifi_connect();
		    ESP_LOGE(TAG,"fail to reconnect_to_wifi");
		   
		}
		vTaskDelay(100/1);
	}
}


static void example_ledc_init(void)
{
    // Prepare and then apply the LEDC PWM timer configuration
    ledc_timer_config_t ledc_timer = {
        .speed_mode       = LEDC_MODE,
        .duty_resolution  = LEDC_DUTY_RES,
        .timer_num        = LEDC_TIMER,
        .freq_hz          = LEDC_FREQUENCY,  // Set output frequency at 4 kHz
        .clk_cfg          = LEDC_AUTO_CLK
    };
    ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

    // Prepare and then apply the LEDC PWM channel configuration
    ledc_channel_config_t ledc_channel_0 = {
        .speed_mode     = LEDC_MODE,
        .channel        = LEDC_CHANNEL_0,
        .timer_sel      = LEDC_TIMER,
        .intr_type      = LEDC_INTR_DISABLE,
        .gpio_num       = LEDC_OUTPUT_IO_C,
        .duty           = 0, // Set duty to 0%
        .hpoint         = 0
    };
    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_0));

    ledc_channel_config_t ledc_channel_1 = {
        .speed_mode     = LEDC_MODE,
        .channel        = LEDC_CHANNEL_1,
        .timer_sel      = LEDC_TIMER,
        .intr_type      = LEDC_INTR_DISABLE,
        .gpio_num       = LEDC_OUTPUT_IO_M,
        .duty           = 0, // Set duty to 0%
        .hpoint         = 0
    };
    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_1));
}

void led_test_c(uint32_t c){


    printf("%"PRIu32" ",c);
    uint32_t LEDC_DUTY_C=LEDC_DUTY*c/100;
    nowlight= LEDC_DUTY_C;
    BLUFI_INFO("12345");
    ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_0, LEDC_DUTY_C));
    // Update duty to apply the new value
    ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_0));
}
void led_test_m(uint32_t m){

    uint32_t LEDC_DUTY_M=LEDC_DUTY*m/100;
    ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_1, LEDC_DUTY_M));
    // Update duty to apply the new value
    ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_1));

}

void led_test_fade_c(uint32_t c){
	
	uint32_t LEDC_DUTY_C=LEDC_DUTY*c/100;
    //ledc_fade_func_install(0);
    nowlight=LEDC_DUTY_C;
    ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_0, LEDC_DUTY_C, 4000);
    ledc_fade_start(LEDC_MODE,LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT);
}
void led_test_fade_m(uint32_t m){
	
	printf("66\n");
	uint32_t LEDC_DUTY_M=LEDC_DUTY*m/100;
    // ledc_fade_func_install(0);

	ledc_set_fade_with_time(LEDC_MODE,
							LEDC_CHANNEL_1, LEDC_DUTY_M, 4000);
	ledc_fade_start(LEDC_MODE,
							LEDC_CHANNEL_1, LEDC_FADE_NO_WAIT);

}

void led_test_sewen(uint32_t m){
	
	uint32_t y= (m- 2700)* (nowlight- 0) / (6500-2700) ;
	printf("%ld\n",y);
	printf("%ld\n",nowlight);
	BLUFI_INFO("sewen:%ld",m);
	ledc_set_fade_with_time(LEDC_MODE,
					LEDC_CHANNEL_0, y, 1000);
	ledc_fade_start(LEDC_MODE,
					LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT);
	ledc_set_fade_with_time(LEDC_MODE,
					LEDC_CHANNEL_1, nowlight-y, 1000);
	ledc_fade_start(LEDC_MODE,
					LEDC_CHANNEL_1, LEDC_FADE_NO_WAIT);
}
void app_main(void)
{
    esp_err_t ret;

    // 初始化NVS
    ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK( ret );
    get_sha256_of_partitions();
    initialise_wifi();
    ret = esp_blufi_controller_init();
    if (ret) {
        BLUFI_ERROR("%s BLUFI controller init failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    ret = esp_blufi_host_and_cb_init(&example_callbacks);
    if (ret) {
        BLUFI_ERROR("%s initialise failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }
	
    BLUFI_INFO("BLUFI VERSION %04x\n", esp_blufi_get_version());
    example_ledc_init();

    ledc_fade_func_install(0);
    ESP_LOGI(TAG, "6666666666!!!!!!!!!!!!!!!!");
	time1[0]='U';
	time1[1]='T';
	time1[2]='C';
	
	
	
}

void sntp(void){
	
    ++boot_count;
	ESP_LOGI(TAG, "Boot count: %d", boot_count);

	time_t now;
	struct tm timeinfo;
	time(&now);
	localtime_r(&now, &timeinfo);
    // Is time set? If not, tm_year will be (1970 - 1900).
    if (timeinfo.tm_year < (2016 - 1900)) {
		
		
	    ESP_LOGI(TAG, "Time is not set yet. Connecting to WiFi and getting time over NTP.");
	    obtain_time();
	    // update 'now' variable with current time
	    time(&now);
	}
#ifdef CONFIG_SNTP_TIME_SYNC_METHOD_SMOOTH
    else {
		
		
		
		// add 500 ms error to the current system time.
		// Only to demonstrate a work of adjusting method!
            {
			
            ESP_LOGI(TAG, "Add a error for test adjtime");
			struct timeval tv_now;
			gettimeofday(&tv_now, NULL);
			int64_t cpu_time = (int64_t)tv_now.tv_sec * 1000000L + (int64_t)tv_now.tv_usec;
			int64_t error_time = cpu_time + 500 * 1000L;
			struct timeval tv_error = { .tv_sec = error_time / 1000000L, .tv_usec = error_time % 1000000L };
			settimeofday(&tv_error, NULL);
		    }
	    ESP_LOGI(TAG, "Time was set, now just adjusting it. Use SMOOTH SYNC method.");
		obtain_time();
		// update 'now' variable with current time
		time(&now);
		}
#endif

    char strftime_buf[32];

	
	setenv("TZ", "CST-8", 1);
	tzset();
	localtime_r(&now, &timeinfo);
	strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
	

	// Read data from the UART

    if (sntp_get_sync_mode() == SNTP_SYNC_MODE_SMOOTH) {
		
        struct timeval outdelta;
        while (sntp_get_sync_status() == SNTP_SYNC_STATUS_IN_PROGRESS) {
			
	        adjtime(NULL, &outdelta);
            ESP_LOGI(TAG, "Waiting for adjusting time ... outdelta = %jd sec: %li ms: %li us",
							  (intmax_t)outdelta.tv_sec,
							  outdelta.tv_usec/1000,
							  outdelta.tv_usec%1000);
			vTaskDelay(2000 / portTICK_PERIOD_MS);
		}
	}

}


void sntp_time(void *arg){
	

	char buf[32];

	int i;
	while(1){
		if(sendbuf[2] == 5){
			
		
	
		
			time_t now;
			struct tm timeinfo;
			time(&now);
			//setenv("TZ", "Asia/Shanghai", 1);
			tzset();
			localtime_r(&now, &timeinfo);

			//printf("%ld %ld\n",now.tv_sec,now.tv_usec);
			strftime(buf, sizeof(buf), "%c", &timeinfo);
			//ESP_LOGI(TAG, "The current date/time in Shanghai is: %s",buf);
			//vTaskDelay(100/1);

		
			//printf("hh:%d\n",timeinfo.tm_hour);
			//printf("mm:%d\n",timeinfo.tm_min);
			if (timeinfo.tm_hour >= morning1 ) {
				
				if(timeinfo.tm_hour == morning1){
				   timeinfo.tm_min = morning2 ;
				} 
				if(timeinfo.tm_hour == night1){
				   timeinfo.tm_min = night2 ;
				} 
				
				if (timeinfo.tm_hour == morning1) {
					led_test_fade_c(1);
					if (timeinfo.tm_min < 15) {
						
						led_test_fade_m(49);
					} else if (timeinfo.tm_min < 30) {
						
						led_test_fade_m(50);
					} else if (timeinfo.tm_min < 45) {
						
						led_test_fade_m(51);
					} else { 
						led_test_fade_m(52);
					}
				}	
				if (timeinfo.tm_hour == morning1+1) {
					
					if (timeinfo.tm_min < 15) {
						led_test_fade_c(1);
						led_test_fade_m(53);
					} else if (timeinfo.tm_min < 30) {
						led_test_fade_c(20);
						led_test_fade_m(54);
					} else if (timeinfo.tm_min < 45) {
						led_test_fade_c(30);
						led_test_fade_m(55);
					} else { 
						led_test_fade_c(40);
						led_test_fade_m(56);
					}
				}	
				if (timeinfo.tm_hour == morning1+2) {
					
					if (timeinfo.tm_min < 15) {
						led_test_fade_c(60);
						led_test_fade_m(58);
					} else if (timeinfo.tm_min < 30) {
						led_test_fade_c(65);
						led_test_fade_m(62);
					} else if (timeinfo.tm_min < 45) {
						led_test_fade_c(68);
						led_test_fade_m(63);
					} else { 
						led_test_fade_c(70);
						led_test_fade_m(65);
					}
				}	
				if (timeinfo.tm_hour == morning1+3) {
					
					if (timeinfo.tm_min < 15) {
						led_test_fade_c(70);
						led_test_fade_m(66);
					} else if (timeinfo.tm_min < 30) {
						led_test_fade_c(75);
						led_test_fade_m(67);
					} else if (timeinfo.tm_min < 45) {
						led_test_fade_c(76);
						led_test_fade_m(68);
					} else { 
						led_test_fade_c(80);
						led_test_fade_m(70);
					}
				}	
				if (timeinfo.tm_hour == morning1+4) {
					
					if (timeinfo.tm_min < 15) {
						led_test_fade_c(85);
						led_test_fade_m(71);
					} else if (timeinfo.tm_min < 30) {
						led_test_fade_c(90);
						led_test_fade_m(73);
					} else if (timeinfo.tm_min < 45) {
						led_test_fade_c(95);
						led_test_fade_m(75);
					} else { 
						led_test_fade_c(95);
						led_test_fade_m(76);
					}
				}	
				
				if (timeinfo.tm_hour >= morning1+5 && timeinfo.tm_hour < morning1+8) {
					
					
						led_test_c(100);
						led_test_fade_m(82);
					
				}	
				
				if (timeinfo.tm_hour == morning1+8) {
					
					if (timeinfo.tm_min < 15) {
						led_test_c(100);
						led_test_fade_m(82);
					} else if (timeinfo.tm_min < 30) {
						led_test_fade_c(95);
						led_test_fade_m(76);
					} else if (timeinfo.tm_min < 45) {
						led_test_fade_c(95);
						led_test_fade_m(75);
					} else { 
						led_test_fade_c(90);
						led_test_fade_m(73);
					}
				}	
				
				if (timeinfo.tm_hour == morning1+9) {
					
					if (timeinfo.tm_min < 15) {
						led_test_fade_c(85);
						led_test_fade_m(71);
					} else if (timeinfo.tm_min < 30) {
						led_test_fade_c(80);
						led_test_fade_m(70);
					} else if (timeinfo.tm_min < 45) {
						led_test_fade_c(76);
						led_test_fade_m(68);
					} else { 
						led_test_fade_c(75);
						led_test_fade_m(67);
					}
				}	
				
				if (timeinfo.tm_hour == morning1+10) {
					
					if (timeinfo.tm_min < 15) {
						led_test_fade_c(70);
						led_test_fade_m(66);
					} else if (timeinfo.tm_min < 30) {
						led_test_fade_c(70);
						led_test_fade_m(65);
					} else if (timeinfo.tm_min < 45) {
						led_test_fade_c(68);
						led_test_fade_m(63);
					} else { 
						led_test_fade_c(65);
						led_test_fade_m(62);
					}
				}	
				
				if (timeinfo.tm_hour == morning1+11) {
					
					if (timeinfo.tm_min < 15) {
						led_test_fade_c(60);
						led_test_fade_m(58);
					} else if (timeinfo.tm_min < 30) {
						led_test_fade_c(40);
						led_test_fade_m(56);
					} else if (timeinfo.tm_min < 45) {
						led_test_fade_c(30);
						led_test_fade_m(55);
					} else { 
						led_test_fade_c(20);
						led_test_fade_m(54);
					}
				}
				
				if (timeinfo.tm_hour == morning1+12) {
					led_test_fade_c(1);
					if (timeinfo.tm_min < 15) {
						
						led_test_fade_m(53);
					} else if (timeinfo.tm_min < 30) {
						
						led_test_fade_m(52);
					} else if (timeinfo.tm_min < 45) {
						
						led_test_fade_m(51);
					} else { 
						
						led_test_fade_m(50);
					}
				}
				if (timeinfo.tm_hour == morning1+13) {
					led_test_fade_c(1);
					led_test_fade_m(49);
				}
			} else {
				
				led_test_c(0);
				led_test_m(0);
			}
	    }
		
	}
	
}
  
void sntp_set_time(char *t){
	
	char buf[32];
    printf("t: %s \n",t);
	
	time_t now;
	struct tm timeinfo;
	time(&now);
	setenv("TZ", t, 1);
	tzset();
	localtime_r(&now, &timeinfo);

	//printf("%ld %ld\n",now.tv_sec,now.tv_usec);
	strftime(buf, sizeof(buf), "%c", &timeinfo);
	ESP_LOGI(TAG, "The current date/time in Shanghai is: %s",buf);
	//vTaskDelay(100/1);
	int year,year1,year2;
	year=1900+timeinfo.tm_year;

	printf("%x\n",year);
	 //printf("%s\n",timeinfo.tm_year);
	printf("%d\n",year);
	year1=year >> 8;
	year2=year & 0xff;
	printf("%d %d\n",year1,year2);
	sendbuf[0]=0x99;
	sendbuf[1]=0x02;
	
	sendbuf[6]=year1;
	sendbuf[7]=year2;
	sendbuf[8]=timeinfo.tm_mon+1;
	sendbuf[9]=timeinfo.tm_mday;
	sendbuf[10]=timeinfo.tm_hour;
	sendbuf[11]=timeinfo.tm_min;
	sendbuf[12]=timeinfo.tm_sec;
	
}


void once_timer(int x){
	
    printf("x:%d\n",x);
    int y=x*1000000*60;
    printf("y:%d\n",y);
    const esp_timer_create_args_t oneshot_timer_args = {
            .callback = &oneshot_timer_callback,
            /* argument specified here will be passed to timer callback function */
            .arg = (void *)change,
            .name = "one-shot"
    };
    esp_timer_handle_t oneshot_timer;
    ESP_ERROR_CHECK(esp_timer_create(&oneshot_timer_args, &oneshot_timer));
    esp_timer_start_once(oneshot_timer, y);

}


void end_timer(int x){
    printf("x:%d\n",x);
    int y=x*1000000*60;
    printf("y:%d\n",y);
    const esp_timer_create_args_t endshot_timer_args = {
            .callback = &endshot_timer_callback,
            /* argument specified here will be passed to timer callback function */
            .arg = NULL,
            .name = "end-shot"
    };
    esp_timer_handle_t endshot_timer;
    ESP_ERROR_CHECK(esp_timer_create(&endshot_timer_args, &endshot_timer));
    esp_timer_start_once(endshot_timer, y);

}

static void oneshot_timer_callback(void* arg)
{
     led_test_sewen(arg);
     BLUFI_INFO("000");
}


#ifdef CONFIG_SNTP_TIME_SYNC_METHOD_CUSTOM
void sntp_sync_time(struct timeval *tv) {
	settimeofday(tv, NULL);
    ESP_LOGI(TAG, "Time is synchronized from custom code");
	sntp_set_sync_status(SNTP_SYNC_STATUS_COMPLETED);
}
#endif

void time_sync_notification_cb(struct timeval *tv) {
	
	ESP_LOGI(TAG, "Notification of a time synchronization event");
}


void print_servers(void){
	
    ESP_LOGI(TAG, "List of configured NTP servers:");

	for (uint8_t i = 0; i < SNTP_MAX_SERVERS; ++i) {
		
		if (esp_sntp_getservername(i)) {
			
			ESP_LOGI(TAG, "server %d: %s", i, esp_sntp_getservername(i));
		} else {
			
			// we have either IPv4 or IPv6 address, let's print it
			char buff[INET6_ADDRSTRLEN];
			ip_addr_t const *ip = esp_sntp_getserver(i);
		    if (ipaddr_ntoa_r(ip, buff, INET6_ADDRSTRLEN) != NULL)
			ESP_LOGI(TAG, "server %d: %s", i, buff);
		}
	}
}

static void obtain_time(void) {
#if LWIP_DHCP_GET_NTP_SRV
	ESP_LOGI(TAG, "Initializing SNTP");
	esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG(CONFIG_SNTP_TIME_SERVER);
	config.start = false;
	 // start SNTP service explicitly (after connecting)
	config.server_from_dhcp = true;
	 // accept NTP offers from DHCP server, if any (need to enable *before* connecting)
	config.renew_servers_after_new_IP = true;
	 // let esp-netif update configured SNTP server(s) after receiving DHCP lease
	config.index_of_first_server = 1;
	 // updates from server num 1, leaving server 0 (from DHCP) intact
	 // configure the event on which we renew servers
#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
	config.ip_event_to_renew = IP_EVENT_STA_GOT_IP;
#else
	config.ip_event_to_renew = IP_EVENT_ETH_GOT_IP;
#endif
	config.sync_cb = time_sync_notification_cb;
	// only if we need the notification function
	esp_netif_sntp_init(&config);

#endif /* LWIP_DHCP_GET_NTP_SRV */

#if LWIP_DHCP_GET_NTP_SRV
	ESP_LOGI(TAG, "Starting SNTP");
	esp_netif_sntp_start();
#if LWIP_IPV6 && SNTP_MAX_SERVERS > 2
	/* This demonstrates using IPv6 address as an additional SNTP server
	* (statically assigned IPv6 address is also possible)
	*/
	ip_addr_t ip6;
	if (ipaddr_aton("2a01:3f7::1", &ip6)) { 
	// ipv6 ntp source "ntp.netnod.se"
	esp_sntp_setserver(2, &ip6);
	}
#endif  //LWIP_IPV6

#else
	ESP_LOGI(TAG, "Initializing and starting SNTP");
#if CONFIG_LWIP_SNTP_MAX_SERVERS > 1
	/* This demonstrates configuring more than one server
	*/
	esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG_MULTIPLE(2，
	ESP_SNTP_SERVER_LIST(CONFIG_SNTP_TIME_SERVER, "pool.ntp.org" ) );
#else
	/*
	* This is the basic default config with one server and starting the service
	*/
	esp_sntp_config_t config =
	ESP_NETIF_SNTP_DEFAULT_CONFIG(CONFIG_SNTP_TIME_SERVER);
#endif
	config.sync_cb = time_sync_notification_cb;     // Note: This is only needed if we want
#ifdef CONFIG_SNTP_TIME_SYNC_METHOD_SMOOTH
	config.smooth_sync = true;
#endif

	esp_netif_sntp_init(&config);
#endif

	print_servers();

 // wait for time to be set
	time_t now = 0;
	struct tm timeinfo = { 0 };
	int retry = 0;
	const int retry_count = 15;
	while (esp_netif_sntp_sync_wait(2000 / portTICK_PERIOD_MS) ==
				   ESP_ERR_TIMEOUT && ++retry < retry_count) {
					   
					   
		ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
	}
	time(&now);
	localtime_r(&now, &timeinfo);

	//ESP_ERROR_CHECK( example_disconnect() );
	//`esp_netif_sntp_deinit();
}
uint16_t verify_crc16(uint8_t *buffer, uint32_t len){
	
    uint32_t i, j;
    uint16_t crc = 0xffff;
    if (NULL == buffer || 0 == len) {
        return -1;
    }    
    for (j = 0; j < len; j++) {
		
        crc ^= buffer[j];
        for (i = 0; i < 8; i++) {   //循环8次
            if ((crc & 0x01) == 1) { 
                crc >>= 1;
                crc ^= 0xa001;
            } else {
                crc >>= 1;
            }
        }
    }    

    return crc;
}

// OTA
esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
    switch (evt->event_id) {
    case HTTP_EVENT_ERROR:
        ESP_LOGD(TAG1, "HTTP_EVENT_ERROR");
        break;
    case HTTP_EVENT_ON_CONNECTED:
        ESP_LOGD(TAG1, "HTTP_EVENT_ON_CONNECTED");
        break;
    case HTTP_EVENT_HEADER_SENT:
        ESP_LOGD(TAG1, "HTTP_EVENT_HEADER_SENT");
        break;
    case HTTP_EVENT_ON_HEADER:
        ESP_LOGD(TAG1, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
        break;
    case HTTP_EVENT_ON_DATA:
        ESP_LOGD(TAG1, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
        break;
    case HTTP_EVENT_ON_FINISH:
        ESP_LOGD(TAG1, "HTTP_EVENT_ON_FINISH");
        break;
    case HTTP_EVENT_DISCONNECTED:
        ESP_LOGD(TAG1, "HTTP_EVENT_DISCONNECTED");
        break;
    case HTTP_EVENT_REDIRECT:
        ESP_LOGD(TAG1, "HTTP_EVENT_REDIRECT");
        break;
    }
    return ESP_OK;
}

void simple_ota_example_task(void *pvParameter)
{
    ESP_LOGI(TAG1, "Starting OTA example task");
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
    esp_netif_t *netif = get_example_netif_from_desc(bind_interface_name);
    if (netif == NULL) {
        ESP_LOGE(TAG1, "Can't find netif from interface description");
        abort();
    }
    struct ifreq ifr;
    esp_netif_get_netif_impl_name(netif, ifr.ifr_name);
    ESP_LOGI(TAG1, "Bind interface name is %s", ifr.ifr_name);
#endif
    esp_http_client_config_t config = {
        .url = CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL,
#ifdef CONFIG_EXAMPLE_USE_CERT_BUNDLE
        .crt_bundle_attach = esp_crt_bundle_attach,
#else
       // .cert_pem = (char *)server_cert_pem_start,
#endif /* CONFIG_EXAMPLE_USE_CERT_BUNDLE */
        .event_handler = _http_event_handler,
        .keep_alive_enable = true,
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
        .if_name = &ifr,
#endif
    };



#ifdef CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK
    config.skip_cert_common_name_check = true;
#endif

    esp_https_ota_config_t ota_config = {
        .http_config = &config,
    };
    ESP_LOGI(TAG1, "Attempting to download update from %s", config.url);
    esp_err_t ret = esp_https_ota(&ota_config);
    if (ret == ESP_OK) {
        ESP_LOGI(TAG1, "OTA Succeed, Rebooting...");
		printf("OTA Succeed, Rebooting..\n");
		sendbuf[13]=01;
        esp_restart();
    } else {
        ESP_LOGE(TAG1, "Firmware upgrade failed");
		sendbuf[13]=0;
    }
    while (1) {
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

static void print_sha256(const uint8_t *image_hash, const char *label)
{
    char hash_print[HASH_LEN * 2 + 1];
    hash_print[HASH_LEN * 2] = 0;
    for (int i = 0; i < HASH_LEN; ++i) {
        sprintf(&hash_print[i * 2], "%02x", image_hash[i]);
    }
    ESP_LOGI(TAG1, "%s %s", label, hash_print);
}

static void get_sha256_of_partitions(void)
{
    uint8_t sha_256[HASH_LEN] = { 0 };
    esp_partition_t partition;

    // get sha256 digest for bootloader
    partition.address   = ESP_BOOTLOADER_OFFSET;
    partition.size      = ESP_PARTITION_TABLE_OFFSET;
    partition.type      = ESP_PARTITION_TYPE_APP;
    esp_partition_get_sha256(&partition, sha_256);
    print_sha256(sha_256, "SHA-256 for bootloader: ");

    // get sha256 digest for running partition
    esp_partition_get_sha256(esp_ota_get_running_partition(), sha_256);
    print_sha256(sha_256, "SHA-256 for current firmware: ");
}

static void http_get_task(void)
{
    const struct addrinfo hints = {
        .ai_family = AF_INET,
        .ai_socktype = SOCK_STREAM,
    };
    struct addrinfo *res;
    struct in_addr *addr;
    int s, r;
    char recv_buf[1400];
    
    
	int err = getaddrinfo(WEB_SERVER, WEB_PORT, &hints, &res);

	if(err != 0 || res == NULL) {
		ESP_LOGE(TAG, "DNS lookup failed err=%d res=%p", err, res);
		vTaskDelay(1000 / portTICK_PERIOD_MS);
		
	}

	/* Code to print the resolved IP.

	   Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */
	addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
	ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", inet_ntoa(*addr));

	s = socket(res->ai_family, res->ai_socktype, 0);
	if(s < 0) {
		ESP_LOGE(TAG, "... Failed to allocate socket.");
		freeaddrinfo(res);
		vTaskDelay(1000 / portTICK_PERIOD_MS);
		
	}
	ESP_LOGI(TAG, "... allocated socket");

	if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
		ESP_LOGE(TAG, "... socket connect failed errno=%d", errno);
		close(s);
		freeaddrinfo(res);
		vTaskDelay(4000 / portTICK_PERIOD_MS);
		
	}

	ESP_LOGI(TAG, "... connected");
	freeaddrinfo(res);

	if (write(s, REQUEST, strlen(REQUEST)) < 0) {
		ESP_LOGE(TAG, "... socket send failed");
		close(s);
		vTaskDelay(4000 / portTICK_PERIOD_MS);
		
	}
	ESP_LOGI(TAG, "... socket send success");

   
	
   
	bzero(recv_buf, sizeof(recv_buf));
	r = read(s, recv_buf, sizeof(recv_buf)-1);
		
	for(int i = 0; i < r; i++) {
		
		putchar(recv_buf[i]);
		time1[3] = recv_buf[907];
		time1[4] = recv_buf[908];
		time1[5] = recv_buf[909];
			
		}
	
	
	close(s);
	vTaskDelay(1000 / portTICK_PERIOD_MS);
	
	ESP_LOGI(TAG, "Starting again!");

}

void become(void){
	
    if(time1[3] == '-') {
		
		time1[3] = '+';
	} else {
		time1[3] = '-';
	}	
		
		
}